import { Injectable } from '@nestjs/common';
import { PrismaService } from 'src/prisma/prisma.service';
import { transformToOption } from 'src/utils';
import { CreateDictDto } from './dto/create-dict.dto';
import { FindAllDictDto } from './dto/find-all-dict.dto';
import { UpdateDictDto } from './dto/update-dict.dto';

@Injectable()
export class DictService {
  constructor(private prisma: PrismaService) {}
  /**
   * 此 TypeScript 函数根据提供的查询参数异步查找并返回字典项列表。
   * @param {FindAllDictDto} query - 您提供的 `findAll` 函数是一个异步函数，它采用 `FindAllDictDto` 类型的 `query`
   * 参数。此函数负责使用 Prisma 查询数据库，以根据提供的查询参数查找字典。
   * @returns `findAll` 函数返回一个具有两个属性的对象：`list` 和 `total`。`list` 属性包含符合查询条件的字典数组，每个字典包含
   * `id`、`name`、`status` 和 `value` 字段。`total` 属性包含符合查询条件的字典总数。
   */
  async findAll(query: FindAllDictDto) {
    const queryWhere = {
      name: {
        contains: query.name,
      },
      typeCode: {
        contains: query.typeCode,
      },
    };
    const [types, count] = await this.prisma.$transaction([
      this.prisma.dict.findMany({
        where: queryWhere,
        orderBy: {
          id: 'desc',
        },
        skip: (query.pageNum - 1) * query.pageSize,
        take: query.pageSize,
        select: {
          id: true,
          name: true,
          status: true,
          value: true,
        },
      }),
      this.prisma.dict.count({
        where: queryWhere,
      }),
    ]);

    return {
      list: types,
      total: count,
    };
  }

  /**
   * 函数“findForm”使用其 ID 从数据库中检索特定表单。
   * @param {number} id - `id` 参数是用于在数据库中定位特定表单的唯一标识符。它在 `findUnique` 方法的 `where` 子句中用于搜索具有匹配 `id`
   * 值的表单。
   * @returns `findForm` 函数根据提供的 `id` 返回具有指定属性（id、name、remark、typeCode、status、sort、value）的表单对象。使用
   * `findUnique` 方法从 Prisma `dict` 模型中检索表单对象，其中 `where` 子句指定要匹配的 `id`。
   */
  findForm(id: number) {
    return this.prisma.dict.findUnique({ where: { id }, select: { id: true, name: true, remark: true, typeCode: true, status: true, sort: true, value: true } });
  }

  /**
   * 该函数在检查新字典类型是否已经存在后，创建一个新的字典类型。
   * @param {CreateDictDto} body - 您提供的“create”函数是一个异步函数，它使用 Prisma 在数据库中创建一个新的字典条目。
   * @returns `create` 方法返回使用 `prisma.dict.create` 方法和提供的 `body` 数据创建新字典类型的结果。
   */
  async create(body: CreateDictDto) {
    // 检查字典类型是否已经存在
    const existingDict = await this.prisma.dict.findFirst({
      where: { name: body.name },
    });

    if (existingDict) {
      throw new Error('字典已经存在');
    }

    // 如果字典类型不存在，那么创建新字典类型
    return this.prisma.dict.create({
      data: body,
    });
  }

  /**
   * 函数“update”以“id”和“data”对象作为参数，并使用提供的数据更新字典条目。
   * @param {number} id - `id` 参数是一个数字，代表要更新的字典条目的唯一标识符。
   * @param {UpdateDictDto} data - `update` 函数中的 `data` 参数是 `UpdateDictDto` 类型。这意味着它应该是一个对象，其中包含要为具有指定
   * `id` 的字典条目更新的字段。`UpdateDictDto` 对象中的字段应该与字段相对应
   * @returns `update` 方法返回使用 Prisma 客户端中提供的 `data` 更新具有指定 `id` 的字典条目的结果。
   */
  update(id: number, data: UpdateDictDto) {
    return this.prisma.dict.update({
      where: {
        id,
      },
      data,
    });
  }

  /**
   * 函数“removeMany”根据提供的 ID 数组从数据库表中删除多条记录。
   * @param {number[]} ids - `ids` 参数是一个数字数组，其中包含要从数据库中删除的项目的 ID。`removeMany` 函数使用这些 ID 一次从数据库中删除多个项目。
   * @returns `removeMany` 函数返回根据提供的 `ids` 数组从 Prisma 数据库的 `dict` 表中删除多条记录的结果。
   */
  removeMany(ids: number[]) {
    return this.prisma.dict.deleteMany({
      where: {
        id: {
          in: ids,
        },
      },
    });
  }

  /**
   * 函数“getOptions”根据给定的类型代码检索选项并将其转换为特定格式。
   * @param {string} typeCode - `typeCode` 参数是一个字符串，用于在查询数据库中的字典条目时过滤结果。它有助于指定应检索的字典条目类型。
   * @returns `getOptions` 函数根据提供的 `typeCode` 返回转换后的选项。它首先使用 Prisma 根据 `typeCode`
   * 从数据库中获取类型，然后使用带有键“value”的 `transformToOption` 函数将这些类型转换为选项。然后该函数返回转换后的选项。
   */
  async getOptions(typeCode: string) {
    const types = await this.prisma.dict.findMany({
      where: {
        typeCode,
      },
    });
    return transformToOption(types, 'value');
  }
}
